package com.hemaapp.hm_FrameWork;

import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.os.Bundle;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.inputmethod.InputMethodManager;

import com.hemaapp.HemaActivityManager;
import com.hemaapp.HemaConfig;
import com.hemaapp.hm_FrameWork.cache.HemaImageCache;
import com.hemaapp.hm_FrameWork.dialog.HemaProgressDialog;
import com.hemaapp.hm_FrameWork.dialog.HemaTextDialog;
import com.hemaapp.hm_FrameWork.image.HemaImageWorker;
import com.hemaapp.hm_FrameWork.model.HemaIntent;
import com.hemaapp.hm_FrameWork.net.HemaNetTask;
import com.hemaapp.hm_FrameWork.net.HemaNetWorker;
import com.hemaapp.hm_FrameWork.result.HemaBaseResult;
import com.hemaapp.hm_FrameWork.util.HemaBaseUtil;
import com.hemaapp.hm_FrameWork.util.HemaLogger;
import com.hemaapp.hm_FrameWork.util.HemaToastUtil;
import com.umeng.analytics.MobclickAgent;

/**
 * 基本框架.
 * 特别注意：
 * 1. setContentView();
 * 应在super.onCreate(savedInstanceState);之前调用否则会导致findView();等初始化方法失效。 该框架内置了网络访问、图片下载、文件下载功能。
 * <p>
 * 2.图片下载使用方法：imageWorker.loadImage(task);
 * </p>
 * <p>
 * 3.集成了log_v(msg)等打印方法以及println(Object)。
 * </p>
 * <pre>
 * 4. 请求网络方法 HemaNetWorker netWorker = {@link #getNetWorker()};
 *              netWorker.login();
 * </pre>
 * <p/>
 * </p>
 */
public abstract class HemaActivity extends Activity {
    private HemaNetWorker netWorker;
    private HemaTextDialog textDialog;
    private HemaProgressDialog progressDialog;

    protected static final String NO_NETWORK = "无网络连接，请检查网络设置。";
    protected static final String FAILED_GETDATA_HTTP = "请求异常。";
    protected static final String FAILED_GETDATA_DATAPARSE = "数据异常。";

    /**
     * 是否已被销毁
     */
    protected boolean isDestroyed = false;
    /**
     * 打印TAG，类名
     */
    private String TAG;
    /**
     * 上下文对象，等同于this
     */
    protected Activity mContext;
    /**
     * 下载图片使用
     */
    public HemaImageWorker imageWorker;
    /**
     * 获取传参使用
     */
    protected Intent mIntent;
    /**
     * 输入法管理器
     */
    protected InputMethodManager mInputMethodManager;
    /**
     * a LayoutInflater
     */
    private LayoutInflater mLayoutInflater;

    protected HemaActivity() {
        TAG = getLogTag();
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        HemaActivityManager.add(this);
        mContext = this;
        imageWorker = new HemaImageWorker(mContext);
        mIntent = getIntent();
        mInputMethodManager = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
        init(savedInstanceState);
    }

    @Override
    protected void onSaveInstanceState(Bundle outState) {
        outState.putSerializable("intent", new HemaIntent(mIntent));
        super.onSaveInstanceState(outState);
    }

    /**
     * 初始化三部曲
     * 1. getExras() 传值
     * 2. findView()  初始化页面
     * 3. setListener() 设置监听
     *
     * @param savedInstanceState
     */
    private void init(Bundle savedInstanceState) {
        if ((savedInstanceState != null)
                && (savedInstanceState.getSerializable("intent") != null)) {
            mIntent = (HemaIntent) savedInstanceState.getSerializable("intent");
        }
        getExras();
        findView();
        setListener();
    }

    @Override
    protected void onDestroy() {
        if (netWorker != null) {
            netWorker.cancelTasks();
            netWorker.setOnTaskExecuteListener(null);
        }
        destroy();
        super.onDestroy();
        recyclePics();// 回收图片
    }

    private void destroy() {
        isDestroyed = true;
        HemaActivityManager.remove(this);
        stopNetThread();// 杀掉网络线程
        if (imageWorker != null)
            imageWorker.clearTasks();// 取消图片下载任务
        HemaToastUtil.cancelAllToast();
    }

    @Override
    public void finish() {
        cancelTextDialog();
        if (progressDialog != null)
            progressDialog.cancelImmediately();
        destroy();
        super.finish();
    }

    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
        switch (keyCode) {
            case KeyEvent.KEYCODE_BACK:
                if (onKeyBack())
                    return true;
                else
                    return super.onKeyDown(keyCode, event);
            case KeyEvent.KEYCODE_MENU:
                if (onKeyMenu())
                    return true;
                else
                    return super.onKeyDown(keyCode, event);
            default:
                break;
        }
        return super.onKeyDown(keyCode, event);
    }


    /**
     * 无网络提示
     *
     * @param task
     */
    protected void noNetWork(HemaNetTask task) {
        noNetWork(task.getId());
    }

    /**
     * 无网络提示
     *
     * @param taskID
     */
    protected void noNetWork(int taskID) {
        noNetWork();
    }

    /**
     * 无网络提示
     */
    protected void noNetWork() {
        HemaToastUtil.showLongToast(mContext, NO_NETWORK);
    }


    /**
     * 返回键拦截,若需要拦截返回true否则false
     * @return
     */
    protected boolean onKeyBack() {
        finish();
        return true;
    }

    /**
     * 菜单键拦截,若需要拦截返回true否则false
     * @return
     */
    protected boolean onKeyMenu() {
        // TODO Auto-generated method stub
        return false;
    }

    /**
     * 初始化三部曲之：查找控件
     */
    protected abstract void findView();

    /**
     * 初始化三部曲之：获取传参
     */
    protected abstract void getExras();

    /**
     * 初始化三部曲之：设置监听
     */
    protected abstract void setListener();

    /**
     * 暴漏给外部的刷新界面方法
     */
    public void fresh() {

    }



    /**
     * 打印v级别信息
     *
     * @param msg
     */
    protected void log_v(String msg) {
        HemaLogger.v(TAG, msg);
    }

    /**
     * 打印d级别信息
     *
     * @param msg
     */
    protected void log_d(String msg) {
        HemaLogger.d(TAG, msg);
    }

    /**
     * 打印i级别信息
     *
     * @param msg
     */
    protected void log_i(String msg) {
        HemaLogger.i(TAG, msg);
    }

    /**
     * 打印w级别信息
     *
     * @param msg
     */
    protected void log_w(String msg) {
        HemaLogger.w(TAG, msg);
    }

    /**
     * 打印e级别信息
     *
     * @param msg
     */
    protected void log_e(String msg) {
        HemaLogger.e(TAG, msg);
    }

    /**
     * 打印
     *
     * @param msg
     */
    protected void println(Object msg) {
        HemaLogger.println(msg);
    }

    /**
     * 判断字符串是否为空
     *
     * @param str
     * @return true如果该字符串为null或者"",否则false
     */
    protected boolean isNull(String str) {
        return HemaBaseUtil.isNull(str);
    }

    /**
     * 判断网络任务是否都已完成
     *
     * @return
     */
    protected boolean isNetTasksFinished() {
        return netWorker == null || netWorker.isNetTasksFinished();
    }

    /**
     * 是否已被销毁
     */
    public boolean isDestroyed() {
        return isDestroyed;
    }

    /**
     * get a LayoutInflater
     */
    public LayoutInflater getLayoutInflater() {
        return mLayoutInflater == null ? mLayoutInflater = LayoutInflater
                .from(this) : mLayoutInflater;
    }

    // 回收图片
    private void recyclePics() {
        HemaImageCache.getInstance(this).reMoveCacheInMemByObj(this);
        HemaImageCache.getInstance(this).recyclePics();
    }

    // 杀掉网络线程
    private void stopNetThread() {
        if (netWorker != null) {
            netWorker.cancelTasks();
        }
    }

    // 获取打印TAG，即类名
    private String getLogTag() {
        return getClass().getSimpleName();
    }


    /**
     * 关闭Activity
     *
     * @param enterAnim 进入Activity的动画,若没有传0即可
     * @param exitAnim  退出Activity的动画,若没有传0即可
     */
    public void finish(int enterAnim, int exitAnim) {
        finish();
        overridePendingTransition(enterAnim, exitAnim);
    }

    /**
     * @param enterAnim 进入Activity的动画,若没有传0即可
     * @param exitAnim  退出Activity的动画,若没有传0即可
     */
    public void startActivityForResult(Intent intent, int requestCode,
                                       int enterAnim, int exitAnim) {
        startActivityForResult(intent, requestCode);
        if (getParent() != null)
            getParent().overridePendingTransition(enterAnim, exitAnim);
        else
            overridePendingTransition(enterAnim, exitAnim);
    }

    /**
     * @param enterAnim 进入Activity的动画,若没有传0即可
     * @param exitAnim  退出Activity的动画,若没有传0即可
     */
    public void startActivity(Intent intent, int enterAnim, int exitAnim) {
        startActivity(intent);
        if (getParent() != null)
            getParent().overridePendingTransition(enterAnim, exitAnim);
        else
            overridePendingTransition(enterAnim, exitAnim);
    }

    /**
     * 显示交互弹窗(默认不可以点击弹窗外侧取消)
     *
     * @param text 弹窗提示语
     */
    public void showProgressDialog(String text) {
        if (progressDialog == null)
            progressDialog = new HemaProgressDialog(this);
        progressDialog.setText(text);
        progressDialog.setCancelable(false);
        progressDialog.show();
    }

    /**
     * 显示交互弹窗
     *
     * @param text       弹窗提示语id
     * @param cancelable 是否可以点击弹窗外侧取消
     */
    public void showProgressDialog(String text, boolean cancelable) {
        if (progressDialog == null)
            progressDialog = new HemaProgressDialog(this);
        progressDialog.setText(text);
        progressDialog.setCancelable(cancelable);
        progressDialog.show();
    }

    /**
     * 显示交互弹窗(默认不可以点击弹窗外侧取消)
     *
     * @param text 弹窗提示语
     */
    public void showProgressDialog(int text) {
        if (progressDialog == null)
            progressDialog = new HemaProgressDialog(this);
        progressDialog.setText(text);
        progressDialog.setCancelable(false);
        progressDialog.show();
    }

    /**
     * 显示交互弹窗
     *
     * @param text       弹窗提示语
     * @param cancelable 是否可以点击弹窗外侧取消
     */
    public void showProgressDialog(int text, boolean cancelable) {
        if (progressDialog == null)
            progressDialog = new HemaProgressDialog(this);
        progressDialog.setText(text);
        progressDialog.setCancelable(cancelable);
        progressDialog.show();
    }

    /**
     * 取消交互弹窗(同时setCancelable(false))
     */
    public void cancelProgressDialog() {
        if (progressDialog != null) {
            progressDialog.setCancelable(false);
            progressDialog.cancel();
        }
    }

    /**
     * 显示提示弹窗
     *
     * @param text 弹窗提示语
     */
    public void showTextDialog(String text) {
        if (textDialog == null)
            textDialog = new HemaTextDialog(this);
        textDialog.setText(text);
        textDialog.show();
    }

    /**
     * 显示提示弹窗
     *
     * @param text 弹窗提示语id
     */
    public void showTextDialog(int text) {
        if (textDialog == null)
            textDialog = new HemaTextDialog(this);
        textDialog.setText(text);
        textDialog.show();
    }

    /**
     * 取消提示弹窗
     */
    public void cancelTextDialog() {
        if (textDialog != null)
            textDialog.cancel();
    }

    /**
     * 获取网络请求工具类
     */
    public HemaNetWorker getNetWorker() {
        if (netWorker == null) {
            netWorker = initNetWorker();
            netWorker
                    .setOnTaskExecuteListener(new NetTaskExecuteListener(this));
        }
        return netWorker;
    }

    /**
     * 初始化NetWorker
     */
    protected abstract HemaNetWorker initNetWorker();

    /**
     * 返回数据前的操作，如显示进度条
     *
     * @param netTask
     */
    protected abstract void callBeforeDataBack(HemaNetTask netTask);

    /**
     * 返回数据后的操作，如关闭进度条
     *
     * @param netTask
     */
    protected abstract void callAfterDataBack(HemaNetTask netTask);

    /**
     * 服务器处理成功
     *
     * @param netTask
     * @param baseResult
     */
    protected abstract void callBackForServerSuccess(HemaNetTask netTask,
                                                     HemaBaseResult baseResult);

    /**
     * 服务器处理失败
     *
     * @param netTask
     * @param baseResult
     */
    protected abstract void callBackForServerFailed(HemaNetTask netTask,
                                                    HemaBaseResult baseResult);

    /**
     * 获取数据失败
     *
     * @param netTask
     * @param failedType 失败原因
     *                   <p>
     *                   See {@link HemaNetWorker#FAILED_DATAPARSE
     *                   HemaNetWorker.FAILED_DATAPARSE},
     *                   {@link HemaNetWorker#FAILED_HTTP HemaNetWorker.FAILED_HTTP},
     *                   {@link HemaNetWorker#FAILED_NONETWORK
     *                   HemaNetWorker.FAILED_NONETWORK}
     *                   </p>
     */
    protected abstract void callBackForGetDataFailed(HemaNetTask netTask,
                                                     int failedType);

    /**
     * 自动登录失败
     *
     * @param netWorker
     * @param netTask
     * @param failedType 如果failedType为0表示服务器处理失败,其余参照
     *                   {@link HemaNetWorker#FAILED_DATAPARSE
     *                   HemaNetWorker.FAILED_DATAPARSE},
     *                   {@link HemaNetWorker#FAILED_HTTP HemaNetWorker.FAILED_HTTP},
     *                   {@link HemaNetWorker#FAILED_NONETWORK
     *                   HemaNetWorker.FAILED_NONETWORK}
     * @param baseResult 执行结果(仅当failedType为0时有值,其余为null)
     * @return true表示拦截该任务执行流程,
     * 不会继续调用callBackForServerFailed或者callBackForGetDataFailed方法;
     * false反之
     */
    public abstract boolean onAutoLoginFailed(HemaNetWorker netWorker,
                                              HemaNetTask netTask, int failedType, HemaBaseResult baseResult);

    private class NetTaskExecuteListener extends HemaNetTaskExecuteListener {

        public NetTaskExecuteListener(Context context) {
            super(context);
        }

        @Override
        public void onPreExecute(HemaNetWorker netWorker, HemaNetTask netTask) {
            callBeforeDataBack(netTask);
        }

        @Override
        public void onPostExecute(HemaNetWorker netWorker, HemaNetTask netTask) {
            callAfterDataBack(netTask);
        }

        @Override
        public void onServerSuccess(HemaNetWorker netWorker, HemaNetTask netTask, HemaBaseResult baseResult) {
            callBackForServerSuccess(netTask, baseResult);
        }

        @Override
        public void onServerFailed(HemaNetWorker netWorker, HemaNetTask netTask, HemaBaseResult baseResult) {
            callBackForServerFailed(netTask, baseResult);
        }

        @Override
        public void onExecuteFailed(HemaNetWorker netWorker, HemaNetTask netTask, int failedType) {
            callBackForGetDataFailed(netTask, failedType);
        }

        @Override
        public boolean onAutoLoginFailed(HemaNetWorker netWorker, HemaNetTask netTask, int failedType, HemaBaseResult baseResult) {
            return HemaActivity.this.onAutoLoginFailed(netWorker, netTask,
                    failedType, baseResult);
        }
    }

    // 友盟相关
    @Override
    protected void onResume() {
        super.onResume();
        if (HemaConfig.UMENG_ENABLE)
            MobclickAgent.onResume(this);
    }

    @Override
    protected void onPause() {
        super.onPause();
        if (HemaConfig.UMENG_ENABLE)
            MobclickAgent.onPause(this);
    }
    // 友盟相关end

    /**
     * 判断当前是否有可用网络
     *
     * @return 如果有true否则false
     */
    public boolean hasNetWork() {
        ConnectivityManager con = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
        NetworkInfo info = con.getActiveNetworkInfo();// 获取可用的网络服务
        return info != null && info.isAvailable();
    }
}
